package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name    string
	Age     int
	section string // 私有字段，不能通过反射访问
}

func (p *Person) SayHello() {
	fmt.Printf("Hello, my name is %s and I'm %d years old.\n", p.Name, p.Age)
}

// 实现 String 方法
func (p *Person) String() string {
	return fmt.Sprintf("Person{Name: %s, Age: %d, Section: %s}", p.Name, p.Age, p.section)
}

func (p *Person) SetSection(input string) {
	p.section = input
}

func main() {
	// 创建一个 Person 结构体实例
	p := Person{Name: "Alice", Age: 25}
	pp := &p
	pp.SetSection("new section")

	fmt.Printf("Init Person: %v \n", pp)
	// 获取结构体指针的反射值
	value := reflect.ValueOf(&p)
	// 获取指针指向的结构体值
	elem := value.Elem()

	// 修改 Name 字段
	if nameField := elem.FieldByName("Name"); nameField.IsValid() && nameField.CanSet() {
		nameField.SetString("Bob")
	}

	// 修改 Age 字段
	if ageField := elem.FieldByName("Age"); ageField.IsValid() && ageField.CanSet() {
		ageField.SetInt(30)
	}

	// 尝试修改私有字段 section
	if sectionField := elem.FieldByName("section"); sectionField.IsValid() {
		if sectionField.CanSet() {
			sectionField.SetInt(30)
		} else {
			fmt.Println("Cannot set private field 'section'")
		}
	}

	// 输出修改后的结构体
	fmt.Printf("Modified Person: Name=%s, Age=%d\n", p.Name, p.Age)
}

func mainStructBase() {
	p := Person{Name: "Alice", Age: 25}
	value := reflect.ValueOf(p)

	// 访问结构体字段
	nameField := value.FieldByName("Name")
	ageField := value.FieldByName("Age")

	fmt.Println("Name:", nameField.String())
	fmt.Println("Age:", ageField.Int())

	// 调用结构体方法
	method := value.MethodByName("SayHello")
	if method.IsValid() {
		method.Call(nil)
	}
}

func mainBase() {
	num := 10
	// 获取变量的类型
	t := reflect.TypeOf(num)
	// 获取变量的值
	v := reflect.ValueOf(num)

	fmt.Println("Type:", t)
	fmt.Println("Value:", v)

	// 传递变量的指针
	value := reflect.ValueOf(&num)

	// 获取指针指向的值
	elem := value.Elem()
	if elem.CanSet() {
		// 修改值
		elem.SetInt(20)
	}

	fmt.Println("New value:", num)
}
